--Analizar si las "PARSER_OUTPUT"=>bcd2bin estan estables cuando aparece el rx_done_tick (enable).

-- MANDAME EL BUSY A MI ENABLE, controlar que dure un pulso de clock

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;


entity pseudoTop is
	generic(W:integer:=37;
		  ABUS:integer:=18;  --BUS DE DIRECCION DE LA RAM
		  DBUS: integer:=16; --BUS DE DATOS DE LA RAM
                -- Default settings:
                -- 19200 baud, 8 data bits, 1 stop bit
              DBIT: integer:=8;               -- # data bits
              SB_TICK: integer:=16;   -- # ticks for stop bits. 16/24/32 
              DVSR: integer:= 163;    -- baud rate divisor
              DVSR_BIT: integer:=8   -- # bits of DVSR
		  );
		port( uart_rx: std_logic; --UART
            ad:                        out std_logic_vector(ABUS-1 downto 0); 
            we_n, oe_n:                out std_logic;
            dio_a:                     inout std_logic_vector(DBUS-1 downto 0);
            ce_a_n, ub_a_n, lb_a_n:    out std_logic;
            outX,outY,outZ:            out std_logic_vector(3*DBUS-1 downto 0);
            mem_read_busy_out:         out std_logic;
            read_enable: in std_logic; 
            mode_out: out std_logic
);
				
end entity;

architecture arch of pseudoTop is
--GENERALES
signal clk,reset: std_logic;

--BOARD TOP ??????
signal tick: std_logic;


--UART OUTPUT
signal rx_dout: std_logic_vector(7 downto 0);
signal rx_done_tick: std_logic;
--PARSER OUTPUT
signal is_digit, is_blank, is_esc,is_minus: std_logic;
--BCD2BIN OUTPUT
signal magnitude_bin:std_logic_vector(W-1 downto 0);
signal sign_bin: std_logic;
signal new_coord_flag: std_logic;
--COMPLEMENTO A DOS OUTPUT
signal unsigned_bin: std_logic_vector(W-1 downto 0);
--LOGICA EN EL ADDRESS COUNTER
signal reset_address: std_logic;
signal enable_address_counter: std_logic;

--ADDRESS COUNTER
signal sram_address: std_logic_vector(ABUS-1 downto 0);

--MEMORY LOADER
signal mem_load_crash: std_logic; --HACEMO' ALGO CON ESTO????
signal mem_load, sram_ready: std_logic;
signal sram_write_data_bus: std_logic_vector(DBUS-1 downto 0);

--LOGICA EN EL CONTROLADOR DE MEMORIA
signal mem: std_logic;

--CONTROLADOR DE MEMORIA
signal sram_read_data_bus: std_logic_vector(DBUS-1 downto 0);

--MEMORY READER
signal busy2read: std_logic;

--MODO
signal mode, notmode, esc_flag: std_logic; -- '0'=UART / '1'=VGA

--CONTROL ADDRESS
signal max_address: std_logic_vector(ABUS-1 downto 0);
signal address_overflow: std_logic;

signal mem_read_add_trig,read_enable_aux: std_logic;
signal mem_read: std_logic; --MEM_READ
signal mem_read_busy: std_logic;
---INTERFAZ CON MATIAS 

begin

baud_gen_unit: entity work.mod_m_counter(arch)
	generic map(M=>DVSR, N=>DVSR_BIT)
	port map(clk => clk, reset => reset,
			q=> open, max_tick=> tick);

UART0_RX:entity work.uart_rx(arch)
	generic map(DBIT=>DBIT, SB_TICK=>SB_TICK)
	port map(clk=>clk, reset=>reset, s_tick => tick,
		rx=> uart_rx, rx_done_tick => rx_done_tick,
		dout=> rx_dout);

--UNIDAD DE TRANSMISION. NO ESTA CONECTADA!!!!
--UART0_TX:entity work.uart_tx(arch)
--		generic map(DBIT=>DBIT, SB_TICK=>SB_TICK)
--		port map(clk=>clk, reset=>reset,
--			tx_start=>tx_fifo_not_empty,
--			s_tick=>tick, din=>tx_fifo_out,
--			tx_done_tick=>tx_done_tick, tx=>tx);


PARSER0:entity work.ascii_parser(arch)
	port map (clk=>clk, reset=>reset,ascii => rx_dout, rx_done_tick=>rx_done_tick,
			is_digit=>is_digit, is_blank=> is_blank, is_esc => is_esc, is_minus => is_minus);

BCD2BIN0:entity work.bcd2binV2(arch)
        	generic map(W=>W)
		port map (clk=>clk, reset=>reset, bcd_in=>rx_dout(3 downto 0),
			  dout=>magnitude_bin, new_output_flag => new_coord_flag,
			  sign => sign_bin, is_digit => is_digit, is_blank =>is_blank,
			  is_minus => is_minus, enable=>rx_done_tick);

TWOS0:entity work.twosComplement(arch)
	generic map(W=>W)
	port map(din=>magnitude_bin,dout=>unsigned_bin,sign=>sign_bin);

ADDCOUNT0:entity work.addressCounter(arch)
	generic map (ABUS=>ABUS)
	port map(clk=>clk, reset=>reset_address, enable=>enable_address_counter, -- El enable se dispara con mem.
		address_out=>sram_address);

MEMLOAD0:entity work.memoryLoader(arch)
	generic map (W=>W, DBUS=>DBUS)
	port map(clk=>clk, reset=>reset, crash_flag=>mem_load_crash,
			enable=>is_blank, din=>unsigned_bin, sign_in=>sign_bin,
			mem_out=>mem_load, ready=>sram_ready,
			dout=>sram_write_data_bus);

MEMCTRL0: entity work.sram_ctrl(arch)
	port map(clk=>clk, reset=>reset, mem=>mem,rw=>mode, addr=>sram_address,
			data_f2s=>sram_write_data_bus, ready=>sram_ready,
			data_s2f_r=>open, data_s2f_ur=>sram_read_data_bus, 
			ad=>ad, we_n=>we_n, oe_n=>oe_n, dio_a=>dio_a,
			ce_a_n=>ce_a_n, ub_a_n=>ub_a_n, lb_a_n=>lb_a_n);

MEM_READ0:entity work.memoryReader(arch)
	generic map ( DBUS=>DBUS, WORDS=>3)
	port map (clk => clk, reset => reset, addTrig => mem_read_add_trig,
			read=>read_enable_aux, outX => outX, outY=> outY, outZ=>outZ,
			busy_out=>mem_read_busy, mem_out => mem_read, ready=>sram_ready, 
			din=>sram_read_data_bus); 



--Modo "free running"
read_enable_aux <= NOT mem_read_busy  AND read_enable;

--Control de cambio de modo
--El latch espera que se desocupe la ram para cambiar de modo.
ESC_FFD0:entity work.FFD(arch)
		generic map(W => 1)
		port map(clk=>clk,reset=>reset, set=>is_esc, prevQ(0)=>'1', Q(0)=>esc_flag);

ESC_LATCH0:entity work.LATCH(arch)
		generic map(W => 1)
		port map(reset=>reset, set=>sram_ready, prevQ(0)=>esc_flag, Q(0)=>mode);

--Cableado

--Este latch guarda la maxima dirección
notmode <= not mode;
	
ADD_LATCH:entity work.LATCH(arch)
		generic map(W => ABUS)
		port map(reset=>reset, set=> notmode, prevQ=> sram_address, Q=> max_address);


COMPARADOR0:process(sram_address, max_address)
	begin
	address_overflow<='1';
	if unsigned(sram_address) < unsigned(max_address) then
		address_overflow<='0';
	end if;
end process;

reset_address<= reset OR (address_overflow AND mode );

MUX0:process( mem_read_add_trig, mem_load, mode)	
	begin
	if mode='1' then
		enable_address_counter<=mem_read_add_trig;
	else
		enable_address_counter<=mem_read_add_trig;
	end if;
end process;

MUX1:process( mem_load, mem_read, mode)
	begin
	if mode='1' then
		mem<=mem_read;
	else
		mem<=mem_load;
	end if;
end process;

mode_out <= mode;
end arch;
